from datetime import datetime, date, timedelta, time
from flask import Blueprint, request, jsonify, current_app, g
from sqlalchemy import and_, or_
from flasgger import swag_from
from app import db
from app.models.venue import Venue, VenueTimeSlot
from app.models.order import Order
from app.models.activity import Activity, ActivityParticipant
from app.utils.response import success_response, error_response
from app.utils.decorators import login_required
import json

venue_bp = Blueprint('user_venues', __name__)

@venue_bp.route('', methods=['GET'])
@venue_bp.route('/', methods=['GET'])
@login_required
@swag_from({
    'tags': ['用户-场馆'],
    'summary': '获取场馆列表',
    'description': '''用户查看场馆列表，支持分页和筛选。只显示状态为开放且未删除的场馆。

**🔍 筛选功能：**
- 按场馆类型筛选（如：篮球场、足球场、羽毛球场等）
- 按位置筛选（如：北京、上海、广州等）
- 按关键词搜索（场馆名称、描述等）
- 支持分页查询

**📊 返回数据：**
- 场馆基本信息（名称、类型、地址、描述等）
- 场馆图片列表
- 容量和设施信息
- 价格信息
- 开放状态
    ''',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'Authorization',
            'in': 'header',
            'required': True,
            'type': 'string',
            'description': 'JWT token，格式：Bearer {token}，从登录接口获取'
        },
        {
            'name': 'page',
            'in': 'query',
            'type': 'integer',
            'default': 1,
            'description': '页码，从1开始，用于分页查询',
            'example': 1
        },
        {
            'name': 'perPage',
            'in': 'query',
            'type': 'integer',
            'default': 10,
            'description': '每页数量，建议10-50之间，最大100',
            'example': 10
        },
        {
            'name': 'type',
            'in': 'query',
            'type': 'string',
            'description': '场馆类型筛选，如：basketball（篮球场）、football（足球场）、badminton（羽毛球场）、tennis（网球场）等',
            'example': 'basketball'
        },
        {
            'name': 'location',
            'in': 'query',
            'type': 'string',
            'description': '场馆位置筛选，支持城市名或区域名，如：北京、朝阳区、海淀区等',
            'example': '北京'
        },
        {
            'name': 'keyword',
            'in': 'query',
            'type': 'string',
            'description': '搜索关键词，支持场馆名称和描述的模糊搜索',
            'example': '篮球场'
        }
    ],
    'responses': {
        '200': {
            'description': '获取成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '获取成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'total': {'type': 'integer', 'description': '总记录数'},
                            'pages': {'type': 'integer', 'description': '总页数'},
                            'page': {'type': 'integer', 'description': '当前页码'},
                            'perPage': {'type': 'integer', 'description': '每页数量'},
                            'venues': {
                                'type': 'array',
                                'description': '场馆列表',
                                'items': {
                                    'type': 'object',
                                    'properties': {
                                        'id': {'type': 'integer', 'description': '场馆ID'},
                                        'name': {'type': 'string', 'description': '场馆名称'},
                                        'type': {'type': 'string', 'description': '场馆类型'},
                                        'location': {'type': 'string', 'description': '场馆位置'},
                                        'description': {'type': 'string', 'description': '场馆描述'},
                                        'images': {'type': 'array', 'description': '场馆图片URL列表'},
                                        'capacity': {'type': 'integer', 'description': '场馆容量'},
                                        'equipment': {'type': 'string', 'description': '设施设备'},
                                        'price_info': {'type': 'object', 'description': '价格信息'}
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        '401': {
            'description': '未授权访问',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 401},
                    'message': {'type': 'string', 'example': '未授权访问'}
                }
            }
        },
        '500': {
            'description': '服务器内部错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 500},
                    'message': {'type': 'string', 'example': '获取失败'}
                }
            }
        }
    }
})
def get_venues():
    """获取场馆列表"""
    try:
        # 获取查询参数
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('perPage', 10, type=int)
        venue_type = request.args.get('type')
        location = request.args.get('location')
        keyword = request.args.get('keyword')
        
        # 构建查询
        query = Venue.query.filter_by(status=1, is_deleted=False)  # 只查询开放且未删除的场馆
        
        # 应用筛选条件
        if venue_type:
            query = query.filter_by(type=venue_type)
        if location:
            query = query.filter_by(location=location)
        if keyword:
            query = query.filter(or_(
                Venue.name.like(f'%{keyword}%'),
                Venue.description.like(f'%{keyword}%')
            ))
        
        # 分页查询
        pagination = query.order_by(Venue.id.desc()).paginate(page=page, per_page=per_page)
        venues = pagination.items
        
        # 构建响应
        return success_response({
            'total': pagination.total,
            'pages': pagination.pages,
            'page': page,
            'perPage': per_page,
            'venues': [venue.to_dict() for venue in venues]
        }, '获取成功')
        
    except Exception as e:
        current_app.logger.error(f"获取场馆列表失败: {str(e)}")
        return error_response('获取失败', 500)

@venue_bp.route('/<int:venue_id>', methods=['GET'])
@login_required
@swag_from({
    'tags': ['用户-场馆'],
    'summary': '获取场馆详情',
    'description': '''用户查看场馆详细信息，包含场馆基本信息、设施设备、预约规则和时间段等。

**📋 返回信息包括：**
- 场馆基本信息（名称、类型、地址、描述等）
- 场馆图片列表
- 容量和设施设备信息
- 预约规则和注意事项
- 可预约时间段列表
- 价格信息
- 开放状态和营业时间

**⚠️ 注意事项：**
- 只有状态为开放的场馆才能查看详情
- 已删除的场馆无法访问
    ''',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'Authorization',
            'in': 'header',
            'required': True,
            'type': 'string',
            'description': 'JWT token，格式：Bearer {token}，从登录接口获取'
        },
        {
            'name': 'venue_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '场馆ID，必须是存在的且状态为开放的场馆',
            'example': 1
        }
    ],
    'responses': {
        '200': {
            'description': '获取成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '获取成功'},
                    'data': {
                        'type': 'object',
                        'description': '场馆详细信息',
                        'properties': {
                            'id': {'type': 'integer', 'description': '场馆ID'},
                            'name': {'type': 'string', 'description': '场馆名称'},
                            'type': {'type': 'string', 'description': '场馆类型'},
                            'location': {'type': 'string', 'description': '场馆位置'},
                            'description': {'type': 'string', 'description': '场馆描述'},
                            'images': {'type': 'array', 'description': '场馆图片URL列表'},
                            'capacity': {'type': 'integer', 'description': '场馆容量'},
                            'equipment': {'type': 'string', 'description': '设施设备'},
                            'facilities': {'type': 'string', 'description': '配套设施'},
                            'rules': {'type': 'string', 'description': '预约规则和注意事项'},
                            'timeSlots': {'type': 'array', 'description': '可预约时间段列表'}
                        }
                    }
                }
            }
        },
        '403': {
            'description': '场馆不可用',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 403},
                    'message': {'type': 'string', 'example': '该场馆暂未开放'}
                }
            }
        },
        '404': {
            'description': '场馆不存在',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 404},
                    'message': {'type': 'string', 'example': '场馆不存在'}
                }
            }
        },
        '401': {
            'description': '未授权访问',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 401},
                    'message': {'type': 'string', 'example': '未授权访问'}
                }
            }
        },
        '500': {
            'description': '服务器内部错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 500},
                    'message': {'type': 'string', 'example': '获取失败'}
                }
            }
        }
    }
})
def get_venue_detail(venue_id):
    """获取场馆详情"""
    try:
        venue = Venue.query.get(venue_id)
        if not venue:
            return error_response('场馆不存在', 404)
        
        # 检查场馆是否开放
        if venue.status != 1 or venue.is_deleted:
            return error_response('该场馆暂未开放', 403)
        
        return success_response(venue.to_dict(with_slots=True), '获取成功')
        
    except Exception as e:
        current_app.logger.error(f"获取场馆详情失败: {str(e)}")
        return error_response('获取失败', 500)

@venue_bp.route('/<int:venue_id>/time-slots', methods=['GET'])
@login_required
@swag_from({
    'tags': ['用户-场馆'],
    'summary': '获取场馆时间段',
    'description': '''用户查看场馆在指定日期的可预约时间段，包含价格、容量、已预约数量等信息。

**📋 时间段信息包括：**
- 时间段ID和名称
- 开始时间和结束时间
- 价格信息（按人头或包场）
- 总容量和剩余名额
- 已预约数量
- 可用性状态

**⚠️ 注意事项：**
- 只能查询今天及以后的日期
- 只显示场馆开放的时间段
- 已满员的时间段会标记为不可用
- 价格可能因时间段不同而异
    ''',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'Authorization',
            'in': 'header',
            'required': True,
            'type': 'string',
            'description': 'JWT token，格式：Bearer {token}，从登录接口获取'
        },
        {
            'name': 'venue_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '场馆ID，必须是存在的且状态为开放的场馆',
            'example': 1
        },
        {
            'name': 'date',
            'in': 'query',
            'type': 'string',
            'required': True,
            'description': '查询日期，格式：YYYY-MM-DD，必须是今天或以后的日期',
            'example': '2025-06-27'
        }
            ],
        'responses': {
            '200': {
                'description': '获取成功',
                'schema': {
                    'type': 'object',
                    'properties': {
                        'code': {'type': 'integer', 'example': 200},
                        'message': {'type': 'string', 'example': '获取成功'},
                        'data': {
                            'type': 'object',
                            'description': '时间段信息',
                            'properties': {
                                'venue': {'type': 'object', 'description': '场馆基本信息'},
                                'date': {'type': 'string', 'description': '查询日期'},
                                'dayOfWeek': {'type': 'integer', 'description': '星期几（1-7，1为星期一）'},
                                'timeSlots': {
                                    'type': 'array',
                                    'description': '时间段列表',
                                    'items': {
                                        'type': 'object',
                                        'properties': {
                                            'id': {'type': 'integer', 'description': '时间段ID'},
                                            'start_time': {'type': 'string', 'description': '开始时间'},
                                            'end_time': {'type': 'string', 'description': '结束时间'},
                                            'price': {'type': 'number', 'description': '价格（元）'},
                                            'capacity': {'type': 'integer', 'description': '总容量'},
                                            'booked': {'type': 'integer', 'description': '已预约数量'},
                                            'remaining': {'type': 'integer', 'description': '剩余名额'},
                                            'available': {'type': 'boolean', 'description': '是否可用'}
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            '400': {
                'description': '参数错误',
                'schema': {
                    'type': 'object',
                    'properties': {
                        'code': {'type': 'integer', 'example': 400},
                        'message': {'type': 'string', 'example': '日期格式错误或日期不能早于今天'}
                    }
                }
            },
            '403': {
                'description': '场馆不可用',
                'schema': {
                    'type': 'object',
                    'properties': {
                        'code': {'type': 'integer', 'example': 403},
                        'message': {'type': 'string', 'example': '该场馆暂未开放'}
                    }
                }
            },
            '404': {
                'description': '场馆不存在',
                'schema': {
                    'type': 'object',
                    'properties': {
                        'code': {'type': 'integer', 'example': 404},
                        'message': {'type': 'string', 'example': '场馆不存在'}
                    }
                }
            },
            '401': {
                'description': '未授权访问',
                'schema': {
                    'type': 'object',
                    'properties': {
                        'code': {'type': 'integer', 'example': 401},
                        'message': {'type': 'string', 'example': '未授权访问'}
                    }
                }
            },
            '500': {
                'description': '服务器内部错误',
                'schema': {
                    'type': 'object',
                    'properties': {
                        'code': {'type': 'integer', 'example': 500},
                        'message': {'type': 'string', 'example': '获取失败'}
                    }
                }
            }
    }
})
def get_venue_time_slots(venue_id):
    """获取场馆可预约时间段"""
    try:
        venue = Venue.query.get(venue_id)
        if not venue:
            return error_response('场馆不存在', 404)
        
        # 检查场馆是否开放
        if venue.status != 1 or venue.is_deleted:
            return error_response('该场馆暂未开放', 403)
        
        # 获取查询参数
        date_str = request.args.get('date')
        if not date_str:
            return error_response('缺少日期参数', 400)
        
        try:
            target_date = datetime.strptime(date_str, '%Y-%m-%d').date()
        except ValueError:
            return error_response('日期格式错误，请使用YYYY-MM-DD格式', 400)
        
        # 获取目标日期是星期几 (1-7 代表周一到周日)
        day_of_week = target_date.isoweekday()
        
        # 查询该场馆在指定星期几的时间段
        time_slots = VenueTimeSlot.query.filter_by(
            venue_id=venue_id,
            day_of_week=day_of_week,
            status=1  # 只查询开放的时间段
        ).all()
        
        # 查询已预约的订单
        booked_orders = Order.query.filter(
            Order.venue_id == venue_id,
            Order.reservation_date == target_date,
            Order.status.in_([0, 1, 3])  # 未支付、已支付、已完成的订单
        ).all()
        
        # 统计每个时间段的已预约人数
        slot_bookings = {}
        for order in booked_orders:
            participant_count = order.participant_count or 1  # 默认1人
            if order.time_slot_id in slot_bookings:
                slot_bookings[order.time_slot_id] += participant_count
            else:
                slot_bookings[order.time_slot_id] = participant_count
        
        # 构建可用时间段列表
        available_slots = []
        for slot in time_slots:
            booked_count = slot_bookings.get(slot.id, 0)  # 已预约人数
            remaining = slot.capacity - booked_count
            
            slot_info = slot.to_dict()
            slot_info['booked'] = booked_count
            slot_info['remaining'] = remaining
            slot_info['available'] = remaining > 0
            
            available_slots.append(slot_info)
        
        return success_response({
            'venue': venue.to_dict(),
            'date': date_str,
            'dayOfWeek': day_of_week,
            'timeSlots': available_slots
        }, '获取成功')
        
    except Exception as e:
        current_app.logger.error(f"获取场馆时间段失败: {str(e)}")
        return error_response('获取失败', 500)

@venue_bp.route('/<int:venue_id>/availability', methods=['GET'])
@swag_from({
    'tags': ['用户-场馆'],
    'summary': '查询场馆可用性（公开接口）',
    'description': '查询场馆从指定日期开始的7天内可用性，无需登录。支持单个date参数或start_date/end_date参数。',
    'parameters': [
        {
            'name': 'venue_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '场馆ID'
        },
        {
            'name': 'date',
            'in': 'query',
            'type': 'string',
            'required': False,
            'description': '开始查询日期，格式：YYYY-MM-DD。不传则默认为今天，返回7天数据'
        },
        {
            'name': 'start_date',
            'in': 'query',
            'type': 'string',
            'required': False,
            'description': '开始日期，格式：YYYY-MM-DD（与end_date配合使用）'
        },
        {
            'name': 'end_date',
            'in': 'query',
            'type': 'string',
            'required': False,
            'description': '结束日期，格式：YYYY-MM-DD（与start_date配合使用）'
        }
    ],
    'responses': {
        '200': {
            'description': '查询成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '查询成功'},
                    'data': {'type': 'object', 'description': '包含venue(场馆信息)、dateRange(日期范围)、availability(可用性数组)'}
                }
            }
        }
    }
})
def check_venue_availability(venue_id):
    """查询场馆可用性"""
    try:
        venue = Venue.query.get(venue_id)
        if not venue:
            return error_response('场馆不存在', 404)
        
        # 检查场馆是否开放
        if venue.status != 1 or venue.is_deleted:
            return error_response('该场馆暂未开放', 403)
        
        # 获取查询参数
        date_str = request.args.get('date')
        start_date_str = request.args.get('start_date')
        end_date_str = request.args.get('end_date')
        
        # 如果传了date参数，则查询从该日期开始的7天
        if date_str:
            try:
                start_date = datetime.strptime(date_str, '%Y-%m-%d').date()
                end_date = start_date + timedelta(days=6)  # 7天
                start_date_str = start_date.strftime('%Y-%m-%d')
                end_date_str = end_date.strftime('%Y-%m-%d')
            except ValueError:
                return error_response('日期格式错误，请使用YYYY-MM-DD格式', 400)
        # 如果传了start_date和end_date，则使用原始逻辑
        elif start_date_str and end_date_str:
            try:
                start_date = datetime.strptime(start_date_str, '%Y-%m-%d').date()
                end_date = datetime.strptime(end_date_str, '%Y-%m-%d').date()
            except ValueError:
                return error_response('日期格式错误，请使用YYYY-MM-DD格式', 400)
        # 如果什么都没传，默认从今天开始7天
        else:
            # 使用北京时间
            from datetime import timezone, timedelta
            beijing_tz = timezone(timedelta(hours=8))
            beijing_now = datetime.now(beijing_tz)
            start_date = beijing_now.date()
            end_date = start_date + timedelta(days=6)  # 7天
            start_date_str = start_date.strftime('%Y-%m-%d')
            end_date_str = end_date.strftime('%Y-%m-%d')
        
        if start_date > end_date:
            return error_response('开始日期不能大于结束日期', 400)
        
        # 检查日期范围不能超过30天
        if (end_date - start_date).days > 30:
            return error_response('查询日期范围不能超过30天', 400)
        
        availability = []
        current_date = start_date
        
        while current_date <= end_date:
            day_of_week = current_date.isoweekday()
            
            # 查询该场馆在指定星期几的时间段
            time_slots = VenueTimeSlot.query.filter_by(
                venue_id=venue_id,
                day_of_week=day_of_week,
                status=1
            ).all()
            
            total_slots = len(time_slots)
            
            if total_slots == 0:
                # 该天没有开放时间段
                availability.append({
                    'date': current_date.strftime('%Y-%m-%d'),
                    'dayOfWeek': day_of_week,
                    'available': False,
                    'totalSlots': 0,
                    'availableSlots': 0
                })
            else:
                # 查询已预约的订单
                booked_orders = Order.query.filter(
                    Order.venue_id == venue_id,
                    Order.reservation_date == current_date,
                    Order.status.in_([0, 1, 3])
                ).all()
                
                # 统计已预约的时间段
                booked_slot_ids = set(order.time_slot_id for order in booked_orders)
                available_slots = total_slots - len(booked_slot_ids)
                
                availability.append({
                    'date': current_date.strftime('%Y-%m-%d'),
                    'dayOfWeek': day_of_week,
                    'available': available_slots > 0,
                    'totalSlots': total_slots,
                    'availableSlots': available_slots
                })
            
            current_date += timedelta(days=1)
        
        return success_response({
            'venue': venue.to_dict(),
            'dateRange': {
                'startDate': start_date_str,
                'endDate': end_date_str
            },
            'availability': availability
        }, '查询成功')
        
    except Exception as e:
        current_app.logger.error(f"查询场馆可用性失败: {str(e)}")
        return error_response('查询失败', 500)


@venue_bp.route('/<int:venue_id>/time-range-availability', methods=['GET'])
@swag_from({
    'tags': ['用户-场馆'],
    'summary': '检查场馆特定时间段可用性',
    'description': '''检查场馆在指定开始时间和结束时间段内是否可用，主要用于活动创建时的冲突检查。
    
**📋 功能说明：**
- 检查指定时间段内是否有活动冲突
- 返回冲突的活动详情
- 显示场馆基本信息和容量
- 判断该时间段是否可以预订
- **🆕 如果场馆可用，返回每人价格说明和预订建议**

**💰 价格信息（仅当场馆可用时返回）：**
- 最低、最高和平均每人价格
- 价格范围文本描述
- 建议参与人数和预估费用
- 价格计算说明和注意事项

**⚠️ 注意事项：**
- 必须同时传入开始时间和结束时间
- 时间格式为：YYYY-MM-DD HH:MM:SS
- 开始时间必须早于结束时间
- 主要用于活动冲突检查，不返回详细时间段列表
- 价格信息仅在场馆可用时提供
    ''',
    'parameters': [
        {
            'name': 'venue_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '场馆ID'
        },
        {
            'name': 'start_time',
            'in': 'query',
            'type': 'string',
            'required': True,
            'description': '开始时间，格式：YYYY-MM-DD HH:MM:SS'
        },
        {
            'name': 'end_time',
            'in': 'query',
            'type': 'string',
            'required': True,
            'description': '结束时间，格式：YYYY-MM-DD HH:MM:SS'
        }
    ],
    'responses': {
        '200': {
            'description': '查询成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '查询成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'venue': {
                                'type': 'object',
                                'description': '场馆基本信息',
                                'properties': {
                                    'id': {'type': 'integer'},
                                    'name': {'type': 'string'},
                                    'type': {'type': 'string'},
                                    'address': {'type': 'string'},
                                    'max_capacity': {'type': 'integer'}
                                }
                            },
                            'query_time_range': {
                                'type': 'object',
                                'description': '查询的时间范围',
                                'properties': {
                                    'start_time': {'type': 'string'},
                                    'end_time': {'type': 'string'}
                                }
                            },
                            'available': {'type': 'boolean', 'description': '该时间段是否可用'},
                            'conflicting_activities': {
                                'type': 'array',
                                'description': '冲突的活动列表',
                                'items': {
                                    'type': 'object',
                                    'properties': {
                                        'id': {'type': 'integer'},
                                        'title': {'type': 'string'},
                                        'start_time': {'type': 'string'},
                                        'end_time': {'type': 'string'},
                                        'organizer': {'type': 'string'},
                                        'status': {'type': 'string'}
                                    }
                                }
                            },
                            'conflicting_orders': {
                                'type': 'array',
                                'description': '冲突的订单列表',
                                'items': {
                                    'type': 'object',
                                    'properties': {
                                        'order_id': {'type': 'integer'},
                                        'time_slot': {'type': 'string'},
                                        'participant_count': {'type': 'integer'},
                                        'status': {'type': 'string'}
                                    }
                                }
                            },
                            'availability_details': {
                                'type': 'object',
                                'description': '可用性详细信息',
                                'properties': {
                                    'total_slots_in_range': {'type': 'integer', 'description': '查询时间范围内的总时间段数'},
                                    'available_slots_in_range': {'type': 'integer', 'description': '查询时间范围内可用的时间段数'},
                                    'total_capacity_in_range': {'type': 'integer', 'description': '查询时间范围内的总容量'},
                                    'total_booked_in_range': {'type': 'integer', 'description': '查询时间范围内已预约人数'},
                                    'total_remaining_in_range': {'type': 'integer', 'description': '查询时间范围内剩余可用人数'},
                                    'price_range': {
                                        'type': 'object',
                                        'description': '价格范围',
                                        'properties': {
                                            'min_price': {'type': 'number', 'description': '最低包场价格'},
                                            'max_price': {'type': 'number', 'description': '最高包场价格'},
                                            'min_per_person_price': {'type': 'number', 'description': '最低每人价格'},
                                            'max_per_person_price': {'type': 'number', 'description': '最高每人价格'}
                                        }
                                    },
                                    'affected_time_slots': {
                                        'type': 'array',
                                        'description': '受影响的时间段详情',
                                        'items': {
                                            'type': 'object',
                                            'properties': {
                                                'id': {'type': 'integer'},
                                                'date': {'type': 'string'},
                                                'start_time': {'type': 'string'},
                                                'end_time': {'type': 'string'},
                                                'price': {'type': 'number'},
                                                'per_person_price': {'type': 'number'},
                                                'capacity': {'type': 'integer'},
                                                'booked_count': {'type': 'integer'},
                                                'remaining_capacity': {'type': 'integer'},
                                                'available': {'type': 'boolean'}
                                            }
                                        }
                                    }
                                }
                            },
                            'price_information': {
                                'type': 'object',
                                'description': '价格信息（仅当场馆可用时返回）',
                                'properties': {
                                    'per_person_pricing': {
                                        'type': 'object',
                                        'description': '每人价格信息',
                                        'properties': {
                                            'min_price': {'type': 'number', 'description': '最低每人价格'},
                                            'max_price': {'type': 'number', 'description': '最高每人价格'},
                                            'average_price': {'type': 'number', 'description': '平均每人价格'},
                                            'price_range_text': {'type': 'string', 'description': '价格范围文本描述'},
                                            'total_time_slots': {'type': 'integer', 'description': '涉及的时间段数量'},
                                            'pricing_note': {'type': 'string', 'description': '价格说明'}
                                        }
                                    },
                                    'booking_suggestion': {
                                        'type': 'object',
                                        'description': '预订建议',
                                        'properties': {
                                            'recommended_participant_count': {'type': 'integer', 'description': '建议参与人数'},
                                            'estimated_cost_per_person': {'type': 'number', 'description': '预估每人费用'},
                                            'cost_calculation_note': {'type': 'string', 'description': '费用计算说明'}
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        '400': {
            'description': '参数错误'
        },
        '404': {
            'description': '场馆不存在'
        },
        '403': {
            'description': '场馆不可用'
        }
    }
})
def check_venue_time_range_availability(venue_id):
    """检查场馆特定时间段可用性"""
    try:
        venue = Venue.query.get(venue_id)
        if not venue:
            return error_response('场馆不存在', 404)
        
        # 检查场馆是否开放
        if venue.status != 1 or venue.is_deleted:
            return error_response('该场馆暂未开放', 403)
        
        # 获取查询参数
        start_time_str = request.args.get('start_time')
        end_time_str = request.args.get('end_time')
        
        if not start_time_str or not end_time_str:
            return error_response('缺少开始时间或结束时间参数', 400)
        
        # 解析时间
        try:
            start_time = datetime.strptime(start_time_str, '%Y-%m-%d %H:%M:%S')
            end_time = datetime.strptime(end_time_str, '%Y-%m-%d %H:%M:%S')
        except ValueError:
            return error_response('时间格式错误，请使用 YYYY-MM-DD HH:MM:SS 格式', 400)
        
        if start_time >= end_time:
            return error_response('开始时间必须早于结束时间', 400)
        
        # 检查活动冲突
        from app.models.activity import Activity
        conflicting_activities = Activity.query.filter(
            Activity.venue_id == venue_id,
            Activity.status.in_(['open', 'closed']),  # 排除已取消的活动
            db.or_(
                # 活动开始时间在查询时间段内
                db.and_(Activity.start_time >= start_time, Activity.start_time < end_time),
                # 活动结束时间在查询时间段内
                db.and_(Activity.end_time > start_time, Activity.end_time <= end_time),
                # 活动时间段包含查询时间段
                db.and_(Activity.start_time <= start_time, Activity.end_time >= end_time)
            )
        ).all()
        
        # 检查订单冲突（时间段预订）
        start_date = start_time.date()
        end_date = end_time.date()
        
        conflicting_orders = []
        current_date = start_date
        while current_date <= end_date:
            day_of_week = current_date.isoweekday()
            
            # 查询该场馆在指定星期几的时间段
            time_slots = VenueTimeSlot.query.filter_by(
                venue_id=venue_id,
                day_of_week=day_of_week,
                status=1
            ).all()
            
            for slot in time_slots:
                # 构建时间段的开始和结束时间
                slot_start = datetime.combine(current_date, datetime.strptime(slot.start_time, '%H:%M').time())
                slot_end = datetime.combine(current_date, datetime.strptime(slot.end_time, '%H:%M').time())
                
                # 检查时间段是否与查询时间有重叠
                if (slot_start < end_time and slot_end > start_time):
                    # 查询该时间段的订单
                    orders = Order.query.filter(
                        Order.venue_id == venue_id,
                        Order.time_slot_id == slot.id,
                        Order.reservation_date == current_date,
                        Order.status.in_([0, 1, 3])  # 未支付、已支付、已完成的订单
                    ).all()
                    
                    for order in orders:
                        conflicting_orders.append({
                            'order_id': order.id,
                            'order_no': order.order_no,
                            'time_slot': f"{slot.start_time}-{slot.end_time}",
                            'date': current_date.strftime('%Y-%m-%d'),
                            'participant_count': order.participant_count or 1,
                            'status': {0: '未支付', 1: '已支付', 2: '已取消', 3: '已完成', 4: '已退款'}.get(order.status, '未知')
                        })
            
            current_date += timedelta(days=1)
        
        # 构造冲突活动信息
        conflicting_activity_info = []
        for activity in conflicting_activities:
            # 安全地获取组织者昵称
            organizer_name = '未知'
            if activity.organizer:
                organizer_name = activity.organizer.nickname or '未命名'
            
            conflicting_activity_info.append({
                'id': activity.id,
                'title': activity.title,
                'start_time': activity.start_time.strftime('%Y-%m-%d %H:%M:%S') if activity.start_time else None,
                'end_time': activity.end_time.strftime('%Y-%m-%d %H:%M:%S') if activity.end_time else None,
                'organizer': organizer_name,
                'status': activity.status
            })
        
        # 获取查询时间范围内的时间段详情
        affected_time_slots = []
        total_capacity = 0
        total_booked = 0
        total_slots = 0
        available_slots = 0
        prices = []
        per_person_prices = []
        
        # 查询指定时间范围内的所有时间段
        current_date = start_date
        while current_date <= end_date:
            day_of_week = current_date.isoweekday()
            
            # 获取该星期几的时间段定义
            time_slots = VenueTimeSlot.query.filter_by(
                venue_id=venue_id,
                day_of_week=day_of_week,
                status=1
            ).all()
            
            for slot in time_slots:
                # 构建时间段的开始和结束时间
                slot_start = datetime.combine(current_date, datetime.strptime(slot.start_time, '%H:%M').time())
                slot_end = datetime.combine(current_date, datetime.strptime(slot.end_time, '%H:%M').time())
                
                # 检查时间段是否与查询时间有重叠
                if (slot_start < end_time and slot_end > start_time):
                    # 计算该时间段的预约人数
                    booked_count = db.session.query(db.func.sum(Order.participant_count)).filter(
                        Order.venue_id == venue_id,
                        Order.time_slot_id == slot.id,
                        Order.reservation_date == current_date,
                        Order.status.in_([0, 1, 3])  # 未支付、已支付、已完成的订单
                    ).scalar() or 0
                    
                    remaining_capacity = slot.capacity - booked_count
                    is_slot_available = remaining_capacity > 0
                    
                    total_capacity += slot.capacity
                    total_booked += booked_count
                    total_slots += 1
                    if is_slot_available:
                        available_slots += 1
                    
                    if slot.price:
                        prices.append(float(slot.price))
                    if slot.per_person_price:
                        per_person_prices.append(float(slot.per_person_price))
                    
                    affected_time_slots.append({
                        'id': slot.id,
                    'date': current_date.strftime('%Y-%m-%d'),
                        'start_time': slot.start_time,
                        'end_time': slot.end_time,
                        'price': float(slot.price) if slot.price else None,
                        'per_person_price': float(slot.per_person_price) if slot.per_person_price else None,
                        'capacity': slot.capacity,
                        'booked_count': booked_count,
                        'remaining_capacity': remaining_capacity,
                        'available': is_slot_available
                    })
            
            current_date += timedelta(days=1)
        
        # 构建价格范围信息
        price_range = {
            'min_price': min(prices) if prices else None,
            'max_price': max(prices) if prices else None,
            'min_per_person_price': min(per_person_prices) if per_person_prices else None,
            'max_per_person_price': max(per_person_prices) if per_person_prices else None
        }
        
        # 简化时间段信息，只保留关键数据
        simplified_time_slots = []
        for slot in affected_time_slots:
            simplified_time_slots.append({
                'date': slot['date'],
                'start_time': slot['start_time'],
                'end_time': slot['end_time'],
                'price_per_person': slot['price'],  # price字段实际是每人价格
                'booked_count': slot['booked_count'],
                'remaining_capacity': slot['remaining_capacity']
            })
        
        # 构建简化的可用性详情
        availability_details = {
            'time_slots': simplified_time_slots,
            'total_remaining_capacity': total_capacity - total_booked,
            'total_booked': total_booked
        }
        
        # 判断是否可用
        available = len(conflicting_activities) == 0 and len(conflicting_orders) == 0
        
        # 构建响应数据
        response_data = {
            'venue': {
                'id': venue.id,
                'name': venue.name,
                'type': venue.type,
                'address': venue.address,
                'max_capacity': venue.max_capacity
            },
            'query_time_range': {
                'start_time': start_time_str,
                'end_time': end_time_str
            },
            'available': available,
            'conflicting_activities': conflicting_activity_info,
            'conflicting_orders': conflicting_orders,
            'availability_details': availability_details
        }
        
        # 如果场馆可用，添加价格说明
        if available and simplified_time_slots:
            # 计算价格统计信息
            per_person_prices = [slot['price_per_person'] for slot in simplified_time_slots if slot['price_per_person'] is not None]
            
            if per_person_prices:
                min_price = min(per_person_prices)
                max_price = max(per_person_prices)
                avg_price = sum(per_person_prices) / len(per_person_prices)
                
                # 构建价格说明
                price_description = {
                    'per_person_pricing': {
                        'min_price': min_price,
                        'max_price': max_price,
                        'average_price': round(avg_price, 2),
                        'price_range_text': f"每人 {min_price}-{max_price} 元" if min_price != max_price else f"每人 {min_price} 元",
                        'total_time_slots': len(simplified_time_slots),
                        'pricing_note': "价格可能因时间段不同而有所差异"
                    },
                    'booking_suggestion': {
                        'recommended_participant_count': min(10, venue.max_capacity // 2),
                        'estimated_cost_per_person': round(avg_price, 2),
                        'cost_calculation_note': "实际费用以选择的具体时间段为准"
                    }
                }
                
                response_data['price_information'] = price_description
        
        return success_response(response_data, '查询成功')
        
    except Exception as e:
        current_app.logger.error(f"检查场馆时间段可用性失败: {str(e)}")
        return error_response('查询失败', 500)

def _get_available_slots_for_day(venue_id, target_date):
    """
    辅助函数：获取指定场馆在特定日期的所有可用时间段
    """
    from app.models.order import Order
    from app.models.activity import Activity
    
    day_of_week = target_date.isoweekday()
    
    # 查询该场馆在指定日期的所有开放时间段
    time_slots = VenueTimeSlot.query.filter_by(
        venue_id=venue_id,
        day_of_week=day_of_week,
        status=1
    ).order_by(VenueTimeSlot.start_time).all()

    if not time_slots:
        return []

    # 查询已预订的订单
    booked_orders = Order.query.filter(
        Order.venue_id == venue_id,
        Order.reservation_date == target_date,
        Order.status.in_([0, 1, 3])  # 未支付、已支付、已完成
    ).all()
    booked_slot_ids = {order.time_slot_id for order in booked_orders}

    # 查询冲突的活动
    start_of_day = datetime.combine(target_date, datetime.min.time())
    end_of_day = datetime.combine(target_date, datetime.max.time())
    
    conflicting_activities = Activity.query.filter(
        Activity.venue_id == venue_id,
        Activity.status.in_(['open', 'closed', 'confirmed']),
        Activity.venue_start_time < end_of_day,
        Activity.venue_end_time > start_of_day
    ).all()

    available_slots_info = []
    for slot in time_slots:
        if slot.id in booked_slot_ids:
            continue

        slot_start_datetime = datetime.combine(target_date, datetime.strptime(slot.start_time, '%H:%M').time())
        slot_end_datetime = datetime.combine(target_date, datetime.strptime(slot.end_time, '%H:%M').time())
        
        is_conflicting = False
        for activity in conflicting_activities:
            # 检查活动时间是否与时间段重叠
            if max(activity.venue_start_time, slot_start_datetime) < min(activity.venue_end_time, slot_end_datetime):
                is_conflicting = True
                break
        
        if not is_conflicting:
            available_slots_info.append({
                'id': slot.id,
                'start_time': slot.start_time,
                'end_time': slot.end_time,
                'price': float(slot.price),
                'capacity': slot.capacity,
                'per_person_price': float(slot.per_person_price) if slot.per_person_price else None,
                'min_charge_count': slot.min_charge_count
            })
            
    return available_slots_info


@venue_bp.route('/<int:venue_id>/quick-booking', methods=['POST'])
@login_required
@swag_from({
    'tags': ['用户-场馆'],
    'summary': '一键预定场地',
    'description': '''一键预定场地接口，自动创建私人活动并生成订单。

**🎯 功能特点：**
- 自动创建只有自己可见的私人活动
- 智能选择场地最近可用的时间段
- 根据用户指定的时长自动匹配时间段
- 检查时间段可用性并生成订单
- 支持直接跳转到付款流程

**⚠️ 注意事项：**
- 创建的活动只有活动发起者可见
- 系统会自动寻找从当前时间开始最近的可用时间段
- 时长必须与可用时间段匹配
- 生成的订单状态为待支付

**💡 使用场景：**
- 用户想快速预定场地而不想公开活动
- 个人训练或私人聚会
- 临时场地需求
    ''',
    'security': [{'Bearer': []}],
    'parameters': [
        {
            'name': 'Authorization',
            'in': 'header',
            'required': True,
            'type': 'string',
            'description': 'JWT token，格式：Bearer {token}，从登录接口获取'
        },
        {
            'name': 'venue_id',
            'in': 'path',
            'type': 'integer',
            'required': True,
            'description': '场馆ID，必须是存在的且状态为开放的场馆',
            'example': 1
        },
        {
            'name': 'body',
            'in': 'body',
            'required': True,
            'schema': {
                'type': 'object',
                'required': ['duration_hours'],
                'properties': {
                    'duration_hours': {
                        'type': 'number',
                        'description': '预约时长（小时），支持0.5小时为单位',
                        'example': 2.0,
                        'minimum': 0.5,
                        'maximum': 8.0
                    },
                    'participant_count': {
                        'type': 'integer',
                        'description': '参与人数，默认为1',
                        'example': 3,
                        'minimum': 1,
                        'maximum': 50
                    },
                    'preferred_date': {
                        'type': 'string',
                        'description': '首选日期（YYYY-MM-DD），不传则从今天开始查找',
                        'example': '2025-01-25'
                    },
                    'preferred_start_time': {
                        'type': 'string',
                        'description': '首选开始时间（HH:MM），不传则从当前时间开始查找',
                        'example': '14:00'
                    },
                    'activity_title': {
                        'type': 'string',
                        'description': '活动标题，不传则使用默认标题',
                        'example': '个人训练',
                        'maxLength': 50
                    },
                    'remark': {
                        'type': 'string',
                        'description': '订单备注',
                        'example': '一键预定 - 个人使用',
                        'maxLength': 200
                    }
                }
            }
        }
    ],
    'responses': {
        '200': {
            'description': '预定成功',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 200},
                    'message': {'type': 'string', 'example': '一键预定成功'},
                    'data': {
                        'type': 'object',
                        'properties': {
                            'activity': {
                                'type': 'object',
                                'description': '创建的私人活动信息',
                                'properties': {
                                    'id': {'type': 'integer', 'description': '活动ID'},
                                    'title': {'type': 'string', 'description': '活动标题'},
                                    'is_private': {'type': 'boolean', 'description': '是否私人活动'},
                                    'start_time': {'type': 'string', 'description': '开始时间'},
                                    'end_time': {'type': 'string', 'description': '结束时间'},
                                    'max_participants': {'type': 'integer', 'description': '最大参与人数'}
                                }
                            },
                            'order': {
                                'type': 'object',
                                'description': '生成的订单信息',
                                'properties': {
                                    'id': {'type': 'integer', 'description': '订单ID'},
                                    'order_no': {'type': 'string', 'description': '订单号'},
                                    'amount': {'type': 'number', 'description': '订单金额'},
                                    'status': {'type': 'integer', 'description': '订单状态'},
                                    'reservation_date': {'type': 'string', 'description': '预约日期'},
                                    'start_time': {'type': 'string', 'description': '开始时间'},
                                    'end_time': {'type': 'string', 'description': '结束时间'}
                                }
                            },
                            'venue': {
                                'type': 'object',
                                'description': '场馆信息',
                                'properties': {
                                    'id': {'type': 'integer', 'description': '场馆ID'},
                                    'name': {'type': 'string', 'description': '场馆名称'},
                                    'address': {'type': 'string', 'description': '场馆地址'}
                                }
                            },
                            'matched_time_slots': {
                                'type': 'array',
                                'description': '匹配的时间段列表',
                                'items': {
                                    'type': 'object',
                                    'properties': {
                                        'id': {'type': 'integer', 'description': '时间段ID'},
                                        'date': {'type': 'string', 'description': '日期'},
                                        'start_time': {'type': 'string', 'description': '开始时间'},
                                        'end_time': {'type': 'string', 'description': '结束时间'},
                                        'price': {'type': 'number', 'description': '价格'}
                                    }
                                }
                            },
                            'payment_info': {
                                'type': 'object',
                                'description': '付款信息',
                                'properties': {
                                    'total_amount': {'type': 'number', 'description': '总金额'},
                                    'payment_required': {'type': 'boolean', 'description': '是否需要付款'},
                                    'next_step': {'type': 'string', 'description': '下一步操作提示'}
                                }
                            }
                        }
                    }
                }
            }
        },
        '400': {
            'description': '参数错误或预定失败。当预定失败时，会根据情况返回建议',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 400},
                    'message': {'type': 'string', 'example': '当前时间段已被预订，今天下一个可预订的时间是 16:00，您要预订吗？'},
                    'data': {
                        'type': 'object',
                        'properties': {
                           'suggestion': {
                               'type': 'object',
                               'properties': {
                                   'next_available_start_time': {
                                       'type': 'string', 
                                       'description': '建议的下一个可用时间段的开始时间',
                                       'example': '16:00:00'
                                    }
                               }
                           }
                        }
                    }
                }
            }
        },
        '403': {
            'description': '场馆不可用',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 403},
                    'message': {'type': 'string', 'example': '该场馆暂未开放'}
                }
            }
        },
        '404': {
            'description': '场馆不存在',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 404},
                    'message': {'type': 'string', 'example': '场馆不存在'}
                }
            }
        },
        '409': {
            'description': '时间冲突',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 409},
                    'message': {'type': 'string', 'example': '所选时间段已被预订'}
                }
            }
        },
        '500': {
            'description': '服务器内部错误',
            'schema': {
                'type': 'object',
                'properties': {
                    'code': {'type': 'integer', 'example': 500},
                    'message': {'type': 'string', 'example': '预定失败，请重试'}
                }
            }
        }
    }
})
def quick_booking(venue_id):
    """一键预定场地"""
    # 导入必要的模型
    from app.models.user import User
    from app.models.activity import Activity, ActivityParticipant
    from app.models.order import Order
    from decimal import Decimal
    import uuid
    
    print(f"DEBUG: 一键预定函数被调用，venue_id: {venue_id}")
    try:
        print(f"DEBUG: 进入try块")
        # 验证场馆
        venue = Venue.query.get(venue_id)
        if not venue:
            return error_response('场馆不存在', 404)
        
        print(f"DEBUG: 场馆查找成功: {venue.name}")
        
        # 检查场馆是否开放
        if venue.status != 1 or venue.is_deleted:
            return error_response('该场馆暂未开放', 403)
        
        print(f"DEBUG: 场馆状态正常: status={venue.status}, deleted={venue.is_deleted}")
        
        # 获取当前用户
        current_user_id = g.current_user_id
        print(f"DEBUG: 当前用户ID: {current_user_id}")
        current_user = User.query.get(current_user_id)
        if not current_user:
            print(f"DEBUG: 用户不存在，用户ID: {current_user_id}")
            return error_response('用户不存在', 404)
        print(f"DEBUG: 用户查找成功: {current_user.nickname}")
        
        # 解析请求参数
        data = request.get_json()
        if not data:
            return error_response('请求体不能为空', 400)
        
        duration_hours = data.get('duration_hours')
        if not duration_hours:
            return error_response('缺少必要参数：duration_hours', 400)
        
        try:
            duration_hours = float(duration_hours)
            if duration_hours < 0.5 or duration_hours > 8.0:
                return error_response('预约时长必须在0.5-8.0小时之间', 400)
        except (ValueError, TypeError):
            return error_response('时长格式错误', 400)
        
        participant_count = data.get('participant_count', 1)
        try:
            participant_count = int(participant_count)
            if participant_count < 1 or participant_count > 50:
                return error_response('参与人数必须在1-50人之间', 400)
        except (ValueError, TypeError):
            return error_response('参与人数格式错误', 400)
        
        preferred_date_str = data.get('preferred_date')
        preferred_start_time_str = data.get('preferred_start_time')
        activity_title = data.get('activity_title', '个人场地预约')
        remark = data.get('remark', '一键预定 - 自动生成')
        
        # 获取北京时间
        from datetime import timezone, timedelta
        beijing_tz = timezone(timedelta(hours=8))
        beijing_now = datetime.now(beijing_tz)
        beijing_today = beijing_now.date()
        
        # 解析首选日期
        if preferred_date_str:
            try:
                preferred_date = datetime.strptime(preferred_date_str, '%Y-%m-%d').date()
                if preferred_date < beijing_today:
                    return error_response('首选日期不能早于今天', 400)
            except ValueError:
                return error_response('首选日期格式错误，请使用YYYY-MM-DD格式', 400)
        else:
            preferred_date = beijing_today
            
        # 解析首选开始时间
        preferred_start_time = None
        if preferred_start_time_str:
            try:
                preferred_start_time = datetime.strptime(preferred_start_time_str, '%H:%M').time()
                
                # 检查指定时间不能早于当前时间（只对今天有效）
                if preferred_date == beijing_today:
                    preferred_datetime = datetime.combine(preferred_date, preferred_start_time)
                    beijing_datetime = datetime.combine(beijing_today, beijing_now.time())
                    if preferred_datetime <= beijing_datetime:
                        return error_response(f'指定时间 {preferred_start_time_str} 不能早于当前时间 {beijing_now.strftime("%H:%M")}', 400)
                        
            except ValueError:
                return error_response('首选开始时间格式错误，请使用HH:MM格式', 400)
        
        # 查找可用时间段
        current_app.logger.info(f"开始为场馆{venue_id}查找{duration_hours}小时的可用时间段，从{preferred_date}开始")
        current_app.logger.info(f"当前用户ID: {current_user_id}, 参与人数: {participant_count}")
        
        # 查找从指定日期和当前时间开始的时间段
        now = beijing_now
        
        # 获取首选日期的星期
        day_of_week = preferred_date.isoweekday()
        
        time_slots = VenueTimeSlot.query.filter_by(
            venue_id=venue_id,
            day_of_week=day_of_week,
            status=1
        ).order_by(VenueTimeSlot.start_time).all()
        
        # 确定查找的起始时间
        start_time_for_search = None
        if preferred_start_time:
            # 使用用户指定的开始时间
            start_time_for_search = preferred_start_time
        elif preferred_date == now.date():
            # 今天且没有指定时间，使用当前时间
            start_time_for_search = now.time()
        else:
            # 不是今天且没有指定时间，从场馆最早时间段开始
            start_time_for_search = None
            
        # 首先尝试指定/当前时间点可以开始的时间段
        current_slot = None
        unavailable_reason_text = ""
        available_slots = []
        
        for slot in time_slots:
            slot_start_time = datetime.strptime(slot.start_time, '%H:%M').time()
            slot_end_time = datetime.strptime(slot.end_time, '%H:%M').time()
            
            if start_time_for_search is None:
                # 没有指定时间，选择第一个时间段
                current_slot = slot
                break
            elif preferred_start_time:
                # 指定了开始时间，寻找精确匹配的时间段
                if slot_start_time == start_time_for_search:
                    current_slot = slot
                    break
            else:
                # 没有指定开始时间，但是今天，寻找包含当前时间的时间段
                if slot_start_time <= start_time_for_search < slot_end_time:
                    current_slot = slot
                    break
        
        # 如果没有找到合适的时间段
        if not current_slot and start_time_for_search:
            if preferred_start_time:
                unavailable_reason_text = f"指定时间 {start_time_for_search.strftime('%H:%M')} 无可用时间段"
            else:
                unavailable_reason_text = f"当前时间 {start_time_for_search.strftime('%H:%M')} 无可用时间段"
        
        # 分析时间段可用性
        if current_slot:
            # 检查当前时间段的容量
            slot_start_time = datetime.strptime(current_slot.start_time, '%H:%M').time()
            slot_end_time = datetime.strptime(current_slot.end_time, '%H:%M').time()
            slot_start_datetime = datetime.combine(preferred_date, slot_start_time)
            slot_end_datetime = datetime.combine(preferred_date, slot_end_time)
            slot_duration = (slot_end_datetime - slot_start_datetime).total_seconds() / 3600
            
            # 检查该时间段的容量：只计算活动占用的人数
            
            # (注释掉订单查询逻辑)
            # booked_orders_for_slot = Order.query.filter(...)
            # order_participants = sum(...)
            order_participants = 0 # 直接将订单占用设为0
            
            # 检查活动占用的容量
            conflicting_activities = Activity.query.filter(
                Activity.venue_id == venue_id,
                Activity.status.in_(['open', 'closed']),
                db.or_(
                    db.and_(Activity.venue_start_time >= slot_start_datetime, 
                           Activity.venue_start_time < slot_end_datetime),
                    db.and_(Activity.venue_end_time > slot_start_datetime, 
                           Activity.venue_end_time <= slot_end_datetime),
                    db.and_(Activity.venue_start_time <= slot_start_datetime, 
                           Activity.venue_end_time >= slot_end_datetime)
                )
            ).all()
            
            # 计算活动占用的总人数（按max_participants计算）
            activity_participants = sum(activity.max_participants or 0 for activity in conflicting_activities)
            
            # 总占用人数 = 订单人数(现在为0) + 活动占用人数
            total_occupied = order_participants + activity_participants

            # --- START: 增加详细的诊断日志 ---
            current_app.logger.info(f"一键预定容量检查 - 场馆ID: {venue_id}, 日期: {preferred_date}")
            current_app.logger.info(f"  - 检查时间段: {current_slot.id} ({current_slot.start_time}-{current_slot.end_time}), 总容量: {current_slot.capacity}")
            current_app.logger.info(f"  - 本次请求人数: {participant_count}")
            
            current_app.logger.info(f"  - [订单占用]: {order_participants} 人 (逻辑已修改，始终为0)")
            if booked_orders_for_slot:
                for o in booked_orders_for_slot:
                    current_app.logger.info(f"    - 订单ID: {o.id}, 状态码: {o.status}, 人数: {o.participant_count}, "
                                      f"日期: {o.reservation_date}, time_slot_id: {o.time_slot_id}")
            
            current_app.logger.info(f"  - [活动占用]: {activity_participants} 人")
            if conflicting_activities:
                for a in conflicting_activities:
                    current_app.logger.info(f"    - 活动ID: {a.id}, 标题: '{a.title}', 占用(max_participants): {a.max_participants}")

            current_app.logger.info(f"  - [计算结果]: (已占用 {total_occupied}) + (本次请求 {participant_count}) = {total_occupied + participant_count}")
            current_app.logger.info(f"  - [容量判断]: {total_occupied + participant_count} <= {current_slot.capacity} ? {'是 (容量足够)' if total_occupied + participant_count <= current_slot.capacity else '否 (容量不足)'}")
            # --- END: 增加详细的诊断日志 ---

            # 分析不能预订的原因
            unavailable_reason = []
            if total_occupied + participant_count > current_slot.capacity:
                capacity_remaining = current_slot.capacity - total_occupied
                if capacity_remaining <= 0:
                    unavailable_reason.append("容量已满")
                else:
                    unavailable_reason.append(f"容量不足（剩余{capacity_remaining}人，需要{participant_count}人）")
            
            if slot_duration < duration_hours:
                unavailable_reason.append(f"时长不足（该时间段仅{slot_duration}小时，需要{duration_hours}小时）")

            # 如果当前时间段容量足够且时长足够，直接预定
            if (total_occupied + participant_count <= current_slot.capacity and
                slot_duration >= duration_hours):
                
                # 容量足够，寻找连续的时间段
                available_slots = [{
                    'slot': current_slot,
                    'start_datetime': slot_start_datetime,
                    'end_datetime': slot_end_datetime,
                    'date': preferred_date,
                    'duration': slot_duration
                }]
                
                # 检查是否需要查找更多连续时间段
                remaining_duration = duration_hours - slot_duration
                if remaining_duration > 0:
                    # TODO: 在此实现查找连续时间段的逻辑
                    pass
            else:
                unavailable_reason_text = " 和 ".join(unavailable_reason)

        if not available_slots:
            # 当前时间段不可用，查找下一个可用时间段
            next_available_slot = None
            
            for slot in time_slots:
                slot_start_time = datetime.strptime(slot.start_time, '%H:%M').time()
                
                # 寻找下一个可用时间段的逻辑
                if start_time_for_search:
                    if preferred_start_time:
                        # 指定了时间，寻找该时间之后的时间段
                        if slot_start_time <= start_time_for_search:
                            continue
                    else:
                        # 没指定时间但是今天，寻找当前时间之后的时间段
                        if slot_start_time <= start_time_for_search:
                            continue

                slot_start_datetime = datetime.combine(preferred_date, slot_start_time)
                slot_end_datetime = datetime.combine(preferred_date, datetime.strptime(slot.end_time, '%H:%M').time())
                
                # 检查该时间段的容量：只计算活动占用的人数
                
                # (注释掉订单查询逻辑)
                # booked_orders_for_suggestion_slot = Order.query.filter(...)
                # slot_order_participants = sum(...)
                slot_order_participants = 0 # 直接将订单占用设为0
                
                # 检查该时间段的活动占用
                slot_conflicting_activities = Activity.query.filter(
                    Activity.venue_id == venue_id,
                    Activity.status.in_(['open', 'closed']),
                    db.or_(
                        db.and_(Activity.venue_start_time >= slot_start_datetime, Activity.venue_start_time < slot_end_datetime),
                        db.and_(Activity.venue_end_time > slot_start_datetime, Activity.venue_end_time <= slot_end_datetime),
                        db.and_(Activity.venue_start_time <= slot_start_datetime, Activity.venue_end_time >= slot_end_datetime)
                    )
                ).all()
                
                # 计算活动占用的总人数（按max_participants计算）
                slot_activity_participants = sum(activity.max_participants or 0 for activity in slot_conflicting_activities)
                
                # 总占用人数 = 订单人数(现在为0) + 活动占用人数
                slot_total_occupied = slot_order_participants + slot_activity_participants

                # 检查容量是否足够容纳当前用户
                if slot_total_occupied + participant_count > slot.capacity:
                    continue
                
                # 找到了第一个完全可用的slot
                next_available_slot = slot
                break

            if next_available_slot:
                if preferred_start_time:
                    message = f"指定时间段 {preferred_start_time_str} 不能预订（{unavailable_reason_text}），下一个可预订的时间是 {next_available_slot.start_time}，您要预订吗？"
                else:
                    message = f"当前时间段不能预订（{unavailable_reason_text}），下一个可预订的时间是 {next_available_slot.start_time}，您要预订吗？"
                
                suggestion_data = {
                    'suggestion': {
                        'next_available_start_time': str(next_available_slot.start_time)
                    },
                    'unavailable_reason': unavailable_reason_text
                }
                return error_response(message, 400, data=suggestion_data)
            else:
                # 没有找到下一个可用时间段
                if preferred_start_time:
                    reason_msg = f"指定时间段 {preferred_start_time_str} 不能预订（{unavailable_reason_text}）"
                else:
                    reason_msg = f"当前时间段不能预订（{unavailable_reason_text}）"
                
                if preferred_date == beijing_today:
                    message = f"{reason_msg}，抱歉，该场馆今天已无其他可用时间。"
                else:
                    message = f"{reason_msg}，抱歉，该场馆在 {preferred_date} 已无其他可用时间。"
                
                return error_response(message, 600, data={'unavailable_reason': unavailable_reason_text})
        
        # 简化逻辑：当前时间段可用就直接预定
        found_consecutive_slots = available_slots
        
        # 开始数据库事务
        try:
            # 1. 创建私人活动
            activity_start_time = found_consecutive_slots[0]['start_datetime']
            activity_end_time = found_consecutive_slots[-1]['end_datetime']
             # 定义默认图片
            default_image_url = '/static/38e2c34471be42bcbf831f1ae12795e0.jpeg'
            # 将图片URL包装在JSON数组字符串中
            images_json_string = json.dumps([default_image_url])    

            activity = Activity(
                title=activity_title,
                description=f"一键预定生成的私人活动 - {remark}",
                venue_id=venue_id,
                organizer_id=current_user_id,
                start_time=activity_start_time,      # 必填字段
                end_time=activity_end_time,          # 必填字段  
                venue_start_time=activity_start_time,
                venue_end_time=activity_end_time,
                max_participants=participant_count,
                notes="此活动为一键预定生成的私人活动",  # 标记为私人活动
                status='open',
                activity_type='quick_booking',
                images=images_json_string # <--- 在这里添加默认图片
            )
            
            db.session.add(activity)
            db.session.flush()  # 获取activity_id
            
            # 2. 创建单个订单包含所有时间段
            total_amount = Decimal('0.00')
            
            # 计算总金额
            for slot_info in found_consecutive_slots:
                slot = slot_info['slot']
                total_amount += Decimal(str(slot.price))
            
            # 获取第一个和最后一个时间段的信息
            first_slot_info = found_consecutive_slots[0]
            last_slot_info = found_consecutive_slots[-1]
            first_slot = first_slot_info['slot']
            last_slot = last_slot_info['slot']
            
            # 生成订单号 - 使用北京时间
            beijing_tz = timezone(timedelta(hours=8))
            beijing_now = datetime.now(beijing_tz)
            order_no = f"QB{beijing_now.strftime('%Y%m%d%H%M%S')}{current_user_id:04d}{first_slot.id:03d}"
            
            # 创建单个订单
            order = Order(
                order_no=order_no,
                user_id=current_user_id,
                venue_id=venue_id,
                time_slot_id=first_slot.id,  # 使用第一个时间段ID作为主要时间段
                activity_id=activity.id,
                reservation_date=first_slot_info['date'],
                start_time=first_slot.start_time,
                end_time=last_slot.end_time,  # 结束时间使用最后一个时间段的结束时间
                participant_count=participant_count,
                amount=total_amount,
                status=0,  # 待支付
                remark=f"{remark} - 连续{len(found_consecutive_slots)}个时间段 ({duration_hours}小时)"
            )
            
            db.session.add(order)
            
            # 3. 添加参与者记录
            participant = ActivityParticipant(
                activity_id=activity.id,
                user_id=current_user_id,
                status='joined'  # 使用正确的状态值
            )
            
            db.session.add(participant)
            
            # 提交事务
            db.session.commit()
            
            current_app.logger.info(f"一键预定成功: 用户{current_user_id}预定场馆{venue_id}，活动ID:{activity.id}，订单ID:{order.id}")
            
            # 构建返回数据
            response_data = {
                'activity': {
                    'id': activity.id,
                    'title': activity.title,
                    'is_private': True,
                    'start_time': activity_start_time.strftime('%Y-%m-%d %H:%M:%S'),
                    'end_time': activity_end_time.strftime('%Y-%m-%d %H:%M:%S'),
                    'max_participants': activity.max_participants,
                    'duration_hours': duration_hours,
                    'total_slots': len(found_consecutive_slots)
                },
                'order': {
                    'id': order.id,
                    'order_no': order.order_no,
                    'amount': float(order.amount),
                    'status': order.status,
                    'reservation_date': order.reservation_date.strftime('%Y-%m-%d'),
                    'start_time': str(order.start_time) if order.start_time else None,
                    'end_time': str(order.end_time) if order.end_time else None,
                    'participant_count': order.participant_count
                },
                'venue': {
                    'id': venue.id,
                    'name': venue.name,
                    'address': venue.address
                },
                'matched_time_slots': [
                    {
                        'id': slot_info['slot'].id,
                        'date': slot_info['date'].strftime('%Y-%m-%d'),
                        'start_time': str(slot_info['slot'].start_time) if slot_info['slot'].start_time else None,
                        'end_time': str(slot_info['slot'].end_time) if slot_info['slot'].end_time else None,
                        'price': float(slot_info['slot'].price),
                        'duration': slot_info['duration']
                    }
                    for slot_info in found_consecutive_slots
                ],
                'payment_info': {
                    'total_amount': float(total_amount),
                    'order_count': 1,
                    'payment_required': True,
                    'next_step': '请前往订单页面完成付款'
                },
                'booking_summary': {
                    'venue_name': venue.name,
                    'total_duration': duration_hours,
                    'start_datetime': activity_start_time.strftime('%Y-%m-%d %H:%M'),
                    'end_datetime': activity_end_time.strftime('%Y-%m-%d %H:%M'),
                    'participant_count': participant_count,
                    'is_private_activity': True
                }
            }
            
            return success_response(response_data, '一键预定成功')
            
        except Exception as e:
            # 回滚事务
            db.session.rollback()
            import traceback
            current_app.logger.error(f"一键预定事务失败: {str(e)}")
            current_app.logger.error(f"详细错误信息: {traceback.format_exc()}")
            return error_response(f'预定失败：{str(e)}', 500)
        
    except Exception as e:
        import traceback
        print(f"DEBUG: 外层异常捕获: {str(e)}")
        print(f"DEBUG: 异常堆栈: {traceback.format_exc()}")
        current_app.logger.error(f"一键预定异常: {str(e)}")
        return error_response(f'预定失败：{str(e)}', 500)

def find_max_consecutive_slots(available_slots):
    """查找最长的连续时间段组合"""
    if not available_slots:
        return []
    
    # 按开始时间排序
    slots = sorted(available_slots, key=lambda x: x['start_datetime'])
    
    max_consecutive_group = []
    max_duration = 0
    
    for i in range(len(slots)):
        consecutive_group = [slots[i]]
        total_hours = slots[i]['duration']
        
        # 尝试添加后续连续的时间段
        for j in range(i + 1, len(slots)):
            # 检查是否连续（前一个时间段的结束时间 == 当前时间段的开始时间）
            if consecutive_group[-1]['end_datetime'] == slots[j]['start_datetime']:
                consecutive_group.append(slots[j])
                total_hours += slots[j]['duration']
            else:
                # 不连续，跳出内层循环
                break
        
        # 更新最长的连续组合
        if total_hours > max_duration:
            max_duration = total_hours
            max_consecutive_group = consecutive_group
    
    return max_consecutive_group

def find_consecutive_slots(available_slots, required_hours):
    """
    查找正好满足或最小超过所需时长的连续时间段组合。
    """
    if not available_slots:
        return None
    
    # 按开始时间排序
    slots = sorted(available_slots, key=lambda x: x['start_datetime'])
    
    best_match = None
    min_extra_duration = float('inf')

    # 遍历所有可能的起始点
    for i in range(len(slots)):
        consecutive_group = [slots[i]]
        total_hours = slots[i]['duration']
        
        # 如果单个时间段就满足要求
        if total_hours >= required_hours:
            extra_duration = total_hours - required_hours
            if extra_duration < min_extra_duration:
                min_extra_duration = extra_duration
                best_match = list(consecutive_group) # 修复：确保创建副本

        # 尝试向后拼接
        for j in range(i + 1, len(slots)):
            # 检查时间是否连续
            if consecutive_group[-1]['end_datetime'] == slots[j]['start_datetime']:
                consecutive_group.append(slots[j])
                total_hours += slots[j]['duration']
                
                # 如果当前组合满足要求
                if total_hours >= required_hours:
                    extra_duration = total_hours - required_hours
                    # 我们寻找总时长最接近（即超出最少）的组合
                    if extra_duration < min_extra_duration:
                        min_extra_duration = extra_duration
                        best_match = list(consecutive_group) # 创建一个副本
            else:
                # 不连续，中断拼接
                break
                
    # 如果找到了一个正好等于的，就不再寻找更长的
    if min_extra_duration == 0:
        return best_match

    return best_match

 